<!--
  -    Copyright (c) 2018-2025, cloud All rights reserved.
  -
  - Redistribution and use in source and binary forms, with or without
  - modification, are permitted provided that the following conditions are met:
  -
  - Redistributions of source code must retain the above copyright notice,
  - this list of conditions and the following disclaimer.
  - Redistributions in binary form must reproduce the above copyright
  - notice, this list of conditions and the following disclaimer in the
  - documentation and/or other materials provided with the distribution.
  - Neither the name of the pig4cloud.com developer nor the names of its
  - contributors may be used to endorse or promote products derived from
  - this software without specific prior written permission.
  - Author: cloud
  -->

<template>
  <BasicContainer>
    <FyCurd
      ref="crud"
      v-model="form"
      :option="tableOption"
      :data="list"
      :page.sync="page"
      :table-loading="listLoading"
      :before-open="handleOpenBefore"
      @on-load="getList"
      @search-change="searchChange"
      @refresh-change="refreshChange"
      @size-change="sizeChange"
      @current-change="currentChange"
      @row-update="update"
      @row-save="create">
      <template #menuLeft>
        <ElButton
          v-if="roleManager_btn_add"
          class="filter-item"
          type="primary"
          icon="el-icon-edit"
          @click="handleCreate">
          添加
        </ElButton>
      </template>
      <template #dsScopeForm>
        <div v-if="form.dsType == 1">
          <ElTree
            ref="scopeTree"
            :data="dsScopeData"
            :check-strictly="true"
            :props="defaultProps"
            :default-checked-keys="checkedDsScope"
            class="filter-tree"
            node-key="id"
            highlight-current
            show-checkbox />
        </div>
      </template>

      <template #menu="scope">
        <ElButton
          v-if="roleManager_btn_edit"
          type="text"
          size="small"
          icon="el-icon-edit"
          @click="handleUpdate(scope.row, scope.index)">
          编辑
        </ElButton>
        <ElButton
          v-if="roleManager_btn_del"
          type="text"
          size="small"
          icon="el-icon-delete"
          @click="handleDelete(scope.row, scope.index)">
          删除
        </ElButton>
        <ElButton
          v-if="roleManager_btn_perm"
          type="text"
          size="small"
          icon="el-icon-plus"
          @click="handlePermission(scope.row, scope.index)">
          权限
        </ElButton>
        <ElButton
          v-if="roleManager_btn_perm"
          type="text"
          size="small"
          icon="el-icon-plus"
          @click="handleUser(scope.row, scope.index)">
          用户
        </ElButton>
        <ElButton
          v-if="roleManager_btn_perm"
          type="text"
          size="small"
          icon="el-icon-plus"
          @click="handleMenu(scope.row, scope.index)">
          数据权限编辑
        </ElButton>
      </template>
    </FyCurd>
    <ElementDialog :visible.sync="dialogPermissionVisible" :close-on-click-modal="false" title="分配权限">
      <div class="dialog-main-tree">
        <ElTree
          ref="menuTree"
          :data="treeData"
          :default-checked-keys="checkedKeys"
          :check-strictly="false"
          :props="defaultProps"
          :filter-node-method="filterNode"
          class="filter-tree"
          node-key="id"
          highlight-current
          show-checkbox />
      </div>
      <template #footer>
        <div class="dialog-footer">
          <ElButton type="primary" size="small" @click="updatePermession(roleId)">更 新 </ElButton>
          <ElButton type="default" size="small" @click="cancal()">取消</ElButton>
        </div>
      </template>
    </ElementDialog>
    <TransferUser ref="transferUser" :visible.sync="visibleUser" :role-id="roleId" />
    <MenuRoleTable ref="menuRoleTable" :visible.sync="visibleMenu" />
  </BasicContainer>
</template>

<script>
  import { addObj, delObj, fetchList, fetchRoleTree, permissionUpd, putObj } from '@/api/admin/role'
  import { tableOption } from '@/const/crud/admin/role'
  import { fetchTree } from '@/api/admin/dept'
  import { fetchMenuTree } from '@/api/admin/menu'
  import { mapState } from 'vuex'
  import MenuRoleTable from '@/module/admin/menu/menuRoleTable'
  import { services } from '@/config'

  export default {
    name: 'TableRole',
    components: {
      MenuRoleTable
    },
    data() {
      return {
        searchForm: {},
        tableOption,
        dsScopeData: [],
        treeData: [],
        checkedKeys: [],
        checkedDsScope: [],
        defaultProps: {
          label: 'name',
          value: 'id'
        },
        page: {
          total: 0, // 总页数
          currentPage: 1, // 当前页数
          pageSize: 20 // 每页显示多少条
        },
        menuIds: '',
        list: [],
        listLoading: true,
        form: {},
        roleId: '',
        roleCode: undefined,
        dialogPermissionVisible: false,
        roleManager_btn_add: false,
        roleManager_btn_edit: false,
        roleManager_btn_del: false,
        roleManager_btn_perm: false,
        visibleUser: false,
        visibleMenu: false
      }
    },
    computed: {
      ...mapState('user', ['permissions'])
    },
    created() {
      this.roleManager_btn_add = this.permissions.sys_role_add
      this.roleManager_btn_edit = this.permissions.sys_role_edit
      this.roleManager_btn_del = this.permissions.sys_role_del
      this.roleManager_btn_perm = this.permissions.sys_role_perm
    },
    methods: {
      exportExcel() {
        this.$downBlobFile(`${services.adminService}role/export`, {}, 'role.xlsx')
      },
      handleRefreshChange() {
        this.getList(this.page)
      },
      getList(page, params) {
        this.listLoading = true
        fetchList(
          Object.assign(
            {
              current: page.currentPage,
              size: page.pageSize,
              descs: 'create_time'
            },
            params,
            this.searchForm
          )
        )
          .then(response => {
            this.list = response.data.data.records
            this.page.total = response.data.data.total
            this.listLoading = false
          })
          .catch(() => {
            this.listLoading = false
          })
      },
      refreshChange() {
        this.getList(this.page)
      },
      searchChange(form, done) {
        this.searchForm = form
        this.page.currentPage = 1
        this.getList(this.page, form)
        done()
      },
      sizeChange(pageSize) {
        this.page.pageSize = pageSize
      },
      currentChange(current) {
        this.page.currentPage = current
      },
      handleCreate() {
        this.$refs.crud.rowAdd()
      },
      handleOpenBefore(show, type) {
        window.boxType = type
        fetchTree().then(response => {
          this.dsScopeData = response.data.data
          if (this.form.dsScope) {
            this.checkedDsScope = this.form.dsScope.split(',')
          } else {
            this.checkedDsScope = []
          }
        })
        show()
      },
      handleUpdate(row, index) {
        this.$refs.crud.rowEdit(row, index)
      },
      cancal() {
        this.dialogPermissionVisible = false
      },
      handlePermission(row) {
        fetchRoleTree(row.roleId)
          .then(response => {
            this.checkedKeys = response.data.data
            return fetchMenuTree()
          })
          .then(response => {
            this.treeData = response.data.data
            // 解析出所有的太监节点
            this.checkedKeys = this.resolveAllEunuchNodeId(this.treeData, this.checkedKeys, [])
            this.dialogPermissionVisible = true
            this.roleId = row.roleId
            this.roleCode = row.roleCode
          })
      },
      /**
       * 解析出所有的太监节点id
       * @param json 待解析的json串
       * @param idArr 原始节点数组
       * @param temp 临时存放节点id的数组
       * @return 太监节点id数组
       */
      resolveAllEunuchNodeId(json, idArr, temp) {
        for (let i = 0; i < json.length; i++) {
          const item = json[i]
          // 存在子节点，递归遍历;不存在子节点，将json的id添加到临时数组中
          if (item.children && item.children.length !== 0) {
            this.resolveAllEunuchNodeId(item.children, idArr, temp)
          } else {
            temp.push(idArr.filter(id => id === item.id))
          }
        }
        return temp
      },
      filterNode(value, data) {
        if (!value) return true
        return data.label.indexOf(value) !== -1
      },
      getNodeData(data, done) {
        done()
      },
      handleDelete(row, index) {
        this.$confirm(`是否确认删除名称为"${row.roleName}"` + '"的数据项?', '警告', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
          .then(() => {
            return delObj(row.roleId)
          })
          .then(() => {
            this.getList(this.page)
            this.$notify.success('删除成功')
          })
      },
      handleUser(row) {
        // 关联用户
        this.visibleUser = true
        this.roleId = row.roleId
      },
      handleMenu(row) {
        // 关联用户
        this.visibleMenu = true
        this.roleId = row.roleId
        this.$refs.menuRoleTable.showMenuRoleTable(this.roleId) // 子组件$on中的名字
      },
      create(row, done, loading) {
        if (this.form.dsType === 1) {
          this.form.dsScope = this.$refs.scopeTree.getCheckedKeys().join(',')
        }
        addObj(this.form)
          .then(() => {
            this.getList(this.page)
            done()
            this.$notify.success('创建成功')
          })
          .catch(() => {
            loading()
          })
      },
      update(row, index, done, loading) {
        if (this.form.dsType === 1) {
          this.form.dsScope = this.$refs.scopeTree.getCheckedKeys().join(',')
        }
        putObj(this.form)
          .then(() => {
            this.getList(this.page)
            done()
            this.$notify.success('修改成功')
          })
          .catch(() => {
            loading()
          })
      },
      updatePermession(roleId) {
        this.menuIds = ''
        this.menuIds = this.$refs.menuTree
          .getCheckedKeys()
          .join(',')
          .concat(',')
          .concat(this.$refs.menuTree.getHalfCheckedKeys().join(','))
        permissionUpd(roleId, this.menuIds).then(() => {
          this.dialogPermissionVisible = false
          this.$notify.success('修改成功')
        })
      }
    }
  }
</script>
